﻿using System;
using System.Web;
namespace MikeKappel.Com.CS
{
    public class RewrittenUri : System.Uri
    {
        public enum FileExtensionType
        {
            unknown,
            asmx,
            asp,
            aspx,
            axd,
            gif,
            htm,
            html,
            ico,
            icon,
            info,
            jpg,
            php,
            png,
            torrent,
            txt,
            pdf,
            xml,
            cs,
            vb
        }
        public enum DomainExtensionType
        {
            none,
            com,
            net,
            org,
            edu,
            gov,
            @int,
            mil,
            biz,
            info,
            jobs,
            mobi,
            name,
            tel,
            br,
            ca,
            cn,
            cx,
            fr,
            @in,
            jp,
            ru,
            us
        }
        public struct FileType
        {
            private string _OriginalString;
            private string _Name;
            private FileExtensionType _Extension;
            public FileType(string OriginalString)
            {
                OriginalString = OriginalString.Replace("/", "");
                if (OriginalString.IndexOf(".") <= 0) OriginalString = "Default.aspx";
                if (OriginalString.IndexOf("?") >= 0)
                {
                    OriginalString = OriginalString.Substring(0, OriginalString.IndexOf("?"));
                }
                Int32 LastIndexOfDot = OriginalString.LastIndexOf(".");
                string TempExtension = OriginalString.Substring(LastIndexOfDot + 1, OriginalString.Length - (LastIndexOfDot + 1));
                try
                {
                    _Extension = (FileExtensionType)Enum.Parse(typeof(FileExtensionType), OriginalString.Substring(LastIndexOfDot + 1, OriginalString.Length - (LastIndexOfDot + 1)), true);
                }
                catch
                {
                    _Extension = FileExtensionType.unknown;
                }
                _OriginalString = OriginalString;
                _Name = OriginalString.Substring(0, LastIndexOfDot);
            }
            public string OriginalString
            {
                get { return _OriginalString; }
            }
            public string Name
            {
                get { return _Name; }
            }
            public FileExtensionType Extension
            {
                get { return _Extension; }
            }
            public bool IsImage
            {
                get { return IsImage(this.Extension); }
            }
        }
        public struct DomainType
        {
            private string _OriginalString;
            private string _Name;
            private string _Domain;
            private DomainExtensionType _Extension;
            public DomainType(string OriginalString)
            {
                _OriginalString = OriginalString.Replace("/", "");
                _Name = OriginalString;
                _Domain = OriginalString;
                _Extension = DomainExtensionType.none;
                if (OriginalString.IndexOf(".") >= 0)
                {
                    Int32 LastIndexOfDot = OriginalString.LastIndexOf(".");
                    _OriginalString = OriginalString;
                    _Name = OriginalString.Substring(0, LastIndexOfDot);
                    _Extension = (DomainExtensionType)Enum.Parse(typeof(DomainExtensionType), OriginalString.Substring(LastIndexOfDot + 1, OriginalString.Length - (LastIndexOfDot + 1)), true);
                    if (OriginalString.IndexOf(".") > 0)
                    {
                        string[] ArrHost = OriginalString.Split('.');
                        _Domain = (ArrHost[ArrHost.Length - 2] + "." + ArrHost[ArrHost.Length - 1]).ToLower();
                    }
                    else
                    {
                        _Domain = OriginalString.ToLower();
                    }
                }
            }
            public string OriginalString
            {
                get { return _OriginalString; }
            }
            public string Name
            {
                get { return _Name; }
            }
            public string DomainName
            {
                get { return _Domain; }
            }
            public DomainExtensionType Extension
            {
                get { return _Extension; }
            }
        }

        private bool IsDomainLoaded = false;
        public DomainType Domain
        {
            get
            {
                if (!IsDomainLoaded)
                {
                    _Domain = new DomainType(this.Host);
                    IsDomainLoaded = true;
                }
                return _Domain;
            }
        }
        private DomainType _Domain;

        private bool IsFileLoaded = false;
        public FileType File
        {
            get
            {
                if (!IsFileLoaded)
                {
                    string TempFileName = System.IO.Path.GetFileName(this.PathAndQuery);
                    if (TempFileName.IndexOf(".") > 0)
                    {
                        _File = new FileType(TempFileName);
                        IsFileLoaded = true;
                    }
                    else
                    {
                        foreach (string f in Segments)
                        {
                            if (f.IndexOf(".") > 0)
                            {
                                _File = new FileType(f);
                                IsFileLoaded = true;
                                break; // TODO: might not be correct. Was : Exit For
                            }
                        }
                    }
                    if (!IsFileLoaded)
                    {
                        _File = new FileType("Default.aspx");
                        IsFileLoaded = true;
                    }
                }
                return _File;
            }
        }
        private FileType _File;
        public Boolean IsRewritten
        {
            get
            {
                return isRewritten;
            }
        }
        private Boolean isRewritten = false;
        public RewrittenUri(string RawURL)
            : base(ConvertUrl(RawURL))
        {
            if (RawURL != this.OriginalString)
                isRewritten = true;
        }
        public RewrittenUri(Uri URL)
            : this(URL.OriginalString)
        {
        }
        public static string ConvertUrl(string RawURL)
        {
            string TempFileName = System.IO.Path.GetFileName((new Uri(RawURL)).PathAndQuery);
            if (TempFileName.IndexOf(".") > 0)
            {
                FileType TempFile = new FileType(TempFileName);
                if (TempFile.Extension == FileExtensionType.unknown)
                {
                    RawURL.Replace(TempFileName, TempFileName + "/Default.aspx");
                }
            }
            if (RawURL.IndexOf("?404;") > 0)
            {
                Int32 lenRLP = RawURL.IndexOf("?404;") + 5;
                RawURL = RawURL.Substring(lenRLP, RawURL.Length - lenRLP);
            }
            RawURL = RawURL.Replace(":80", "");
            string AppPath = HttpContext.Current.Request.ApplicationPath;
            if (AppPath.Length > 1 && RawURL.Contains(AppPath))
            {
                RawURL = RawURL.Substring(0, RawURL.IndexOf(AppPath)) + RawURL.Substring(RawURL.IndexOf(AppPath) + AppPath.Length, RawURL.Length - RawURL.IndexOf(AppPath) - AppPath.Length);
            }
            return RawURL;
        }
        public static bool IsImage(FileExtensionType Ext)
        {
            switch (Ext)
            {
                case FileExtensionType.gif:
                    return true;
                case FileExtensionType.jpg:
                    return true;
                case FileExtensionType.png:
                    return true;
                case FileExtensionType.ico:
                    return true;
                case FileExtensionType.icon:
                    return true;
                default:
                    return false;
            }
        }
    }
}